package pl.coldwind.samlis.ag;

import java.util.Random;

/**
 * Simple class for crossing.
 * @author Samlis Coldwind
 *
 */
public class Crossing {

	private static Random rand = new Random();
	
	/**
	 * Depending on type, does crossing of chromoson.
	 * @param chainA/B - chromosons chain
	 * @param type - crossing type
	 * 	0 - half split
	 *  1 - three points
	 *  2 - four points
	 *  3 - 1 point random places
	 *  4 - 2 points random places
	 *  5 - 3 points random places // not implemented yet
	 * @param noWorld - number system - for future use
	 * 2 - binary
	 * 3 - three
	 * 10 - decimal
	 * 16 hex
	 * @return
	 */
	public static String[] cross(String chainA,String chainB, int type, int noWorld){
		
		switch(type){
			case 0:{
				return halfSplit(chainA, chainB);
			}
			case 1:{
				return threePoints(chainA, chainB);
			}
			case 2:{
				return fourPoints(chainA, chainB);
			}
			case 3:{
				return oneRandomPoint(chainA, chainB);
			}
			case 4:{
				return twoRandomPoints(chainA, chainB);
			}
		}
		return null;
	}
	
	/**
	 * Cuts chromoson in half and cross them. 
	 * Before:
	 * AAA|AAA
	 * BBB|BBB
	 * after:
	 * AAA|BBB
	 * BBB|AAA
	 * @param chainA - chromoson A
	 * @param chainB - chromoson B
	 * @return crossed chromosons as a string array
	 */
	private static String[] halfSplit(String chainA,String chainB){
		
		int half = (chainA.length()/2);
		
		return new String[]{
			chainB.substring(0,half)+chainA.substring(half),
			chainA.substring(0,half)+chainB.substring(half),
		};
	}
	
	/**
	 * Cuts chromosons in 3 pieces and mixes them.
	 * before:
	 * AA|AA|AA
	 * BB|BB|BB
	 * after:
	 * BB|AA|BB
	 * AA|BB|AA
	 * @param chainA - chromoson A
	 * @param chainB - chromoson B
	 * @return crossed chromosons as a string array
	 */
	private static String[] threePoints(String chainA, String chainB){
		
		int pointA=chainA.length()/3,
				pointB=pointA*2;
		
		return new String[]{
				chainB.substring(0,pointA)+chainA.substring(pointA,pointB)+chainB.substring(pointB),
				chainA.substring(0,pointA)+chainB.substring(pointA,pointB)+chainA.substring(pointB),
		};
	}
	
	/**
	 * Cuts chromosons in 4 piecies and mixes them.
	 * Before:
	 * AA|AA|AA|AA
	 * BB|BB|BB|BB
	 * After:
	 * BB|AA|BB|AA
	 * AA|BB|AA|BB
	 * @param chainA - chromoson A
	 * @param chainB - Chromoson B
	 * @return mixed chromoson
	 */
	private static String[] fourPoints(String chainA, String chainB){
		int pointA=chainA.length()/4,
			pointB=pointA*2,
			pointC=pointA*3;
		
		return new String[]{
				chainB.substring(0,pointA)+chainA.substring(pointA,pointB)+chainB.substring(pointB,pointC)+chainA.substring(pointC),
				chainA.substring(0,pointA)+chainB.substring(pointA,pointB)+chainA.substring(pointB,pointC)+chainB.substring(pointC)
		};
	}
	
	/**
	 * Splits chromosons in random point and mixes
	 * @param chainA - chromoson A
	 * @param chainB - chromoson b
	 * @return chromosons
	 */
	private static String[] oneRandomPoint(String chainA, String chainB){
		int point = rand.nextInt(chainA.length());
		
		return new String[]{
				chainB.substring(0,point)+chainA.substring(point),
				chainA.substring(0,point)+chainB.substring(point)
		};
		
	}
	
	/**
	 * Sets two random points to cut the chromosons and mixes them.
	 * @param chainA
	 * @param chainB
	 * @return
	 */
	private static String[] twoRandomPoints(String chainA, String chainB){
		int pointA,
			pointB;
		while( ( pointA = rand.nextInt(chainA.length()) ) ==chainA.length());
		
		while((pointB = rand.nextInt(chainA.length())) <=pointA );
		
		return new String[]{
				chainB.substring(0,pointA)+chainA.substring(pointA,pointB)+chainB.substring(pointB),
				chainA.substring(0,pointA)+chainB.substring(pointA,pointB)+chainA.substring(pointB)
		};
		
	}
	
	
}
